﻿#ifndef WRWORKTCPCOMMSERVERTASKDEALER
#define WRWORKTCPCOMMSERVERTASKDEALER

#include "WRWorkTcpCommServerInterface.h"
#include "WRWorkTcpCommServerInterfaceActivator.h"
#include "../WRWorkTcpComm.h"
#include "../WRWorkTcpCommConsts.h"
#include "../../WRSoft-Utility/Framing/WRTaskDealer.h"
#include "../../WRSoft-Utility/Runtime/WRDataPacket.h"
#include <QMutex>
#include <QRunnable>
#include <QThreadPool>

/********************
class ParamsParser
{
public:
    bool parse(T& val, const unsigned char* buf, int len);
};
class ResultWriter
{
public:
    int count(const T& val);
    int write(const T& val, unsigned char* buf);
};
********************/

//表示工作TCP通讯服务器任务处理接口。
template <class T, class TParamsParser, class TResultWriter>
class WRWorkTcpCommServerTaskDealer : public WRWorkTcpCommServerInterface
{
private:
    WRTaskDealer* m_dealer;
    TParamsParser m_parser;
    TResultWriter m_writer;
    QMutex* m_mutex;

    //处理项目。
    class ProcEntry : public QRunnable
    {
    private:
        T m_task;
        WRWorkTcpCommServerTaskDealer* m_owner;
        int m_serial;

    public:
        //初始化处理项目。
        inline ProcEntry(const T& task, WRWorkTcpCommServerTaskDealer* owner, int serial)
            : m_task(task), m_owner(owner), m_serial(serial)
        {
            if (m_owner->affair())
            {
                m_owner->affair()->addRef();
            }
            else
            {
                m_owner->object()->addRef();
            }
        }
        //清理当前对象所占用的相关资源。
        ~ProcEntry(void)
        {
            if (m_owner->affair())
            {
                m_owner->affair()->release();
            }
            else
            {
                m_owner->object()->release();
            }
        }

        //获取参数对象。
        inline T& task(void)
        {
            return m_task;
        }
        //获取参数对象。
        inline const T& task(void) const
        {
            return m_task;
        }

        //获取所有者。
        inline WRWorkTcpCommServerTaskDealer* owner(void) const
        {
            return m_owner;
        }
        //获取序列号。
        inline int serial(void) const
        {
            return m_serial;
        }

        //运行处理。
        void run()
        {
            int result = m_owner->m_dealer->doProcess(&m_task);

            int taskLen = m_owner->m_writer.count(m_task);
            int fillLen = 0;//填充长度
            {
                int remain = taskLen % 8;
                if (remain > 0) fillLen = 8 - remain;
            }

            WRDataPacket* packet;
            if (m_owner->affair())
            {
                char* p;
                int cmdLen = 48 + taskLen + fillLen;
                packet = WRDataPacket::create(cmdLen);
                packet->buffer(&p);

                WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                p += 4;
                WRBytes::write((WR32s)(cmdLen), p);//帧长度
                p += 4;
                WRBytes::write((WR16u)(m_owner->object()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p);//类型（工作事务）
                p += 2;
                WRBytes::write((WR32s)(m_owner->affair()->id()), p);
                p += 4;
                WRBytes::write((WR16u)(m_owner->affair()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p);//类型（接口处理）
                p += 2;
                WRBytes::write((WR16u)(m_owner->index()), p);//接口索引
                p += 4;
                WRBytes::write((WR32s)(m_serial), p);//指令序号
                p += 4;
                WRBytes::write((WR32s)(result), p);//执行结果
                p += 8;
                WRBytes::write((WR32s)(taskLen), p);//参数长度
                p += 4;
                m_owner->m_writer.write(m_task, (unsigned char*)p);//参数数据
                p += taskLen;
                p += fillLen; ;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p);//版本
                p += 4;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p);//帧尾
            }
            else
            {
                char* p;
                int cmdLen = 40 + taskLen + fillLen;
                packet = WRDataPacket::create(cmdLen);
                packet->buffer(&p);

                WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                p += 4;
                WRBytes::write((WR32s)(cmdLen), p);//帧长度
                p += 4;
                WRBytes::write((WR16u)(m_owner->object()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p);//类型（接口处理）
                p += 2;
                WRBytes::write((WR16u)(m_owner->index()), p);//接口索引
                p += 4;
                WRBytes::write((WR32s)(m_serial), p);//指令序号
                p += 4;
                WRBytes::write((WR32s)(result), p);//执行结果
                p += 8;
                WRBytes::write((WR32s)(taskLen), p);//参数长度
                p += 4;
                m_owner->m_writer.write(m_task, (unsigned char*)p);//参数数据
                p += taskLen;
                p += fillLen; ;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p);//版本
                p += 4;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p);//帧尾
            }

            if (!m_owner->sendData(packet))
            {
                packet->release();
            }
        }
    };

public:
    //初始化工作TCP通讯服务器任务处理接口。
    WRWorkTcpCommServerTaskDealer(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommServerObject* target, WRTaskDealer* dealer)
        : WRWorkTcpCommServerInterface(uuid, name, index, target), m_dealer(dealer)
    {
        //add code here
    }
    //初始化工作TCP通讯服务器任务处理接口。
    WRWorkTcpCommServerTaskDealer(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommServerAffair* target, WRTaskDealer* dealer)
        : WRWorkTcpCommServerInterface(uuid, name, index, target), m_dealer(dealer)
    {
        //add code here
    }

    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommServerTaskDealer(void)
    {
        //add code here
    }

    //处理数据。
    void procData(const unsigned char* buf, int len)
    {
        buf += 2;
        len -= 2;
        WR32s serial = WRBytes::read<WR32s>(buf);
        buf += 4;
        len -= 4;
        WR32s taskLen = WRBytes::read<WR32s>(buf);;
        buf += 4;
        len -= 4;

        T task;
        if (taskLen <= len && m_parser.parse(task, (const unsigned char*)buf, taskLen))
        {
            ProcEntry* procEntry = new ProcEntry(task, this, serial);
            QThreadPool::globalInstance()->start(procEntry);
        }
        else
        {
            //add code here on parsing failed!
        }
    }
};

//表示工作TCP通讯服务器任务处理激活器。
template <class T, class TParamsParser, class TResultWriter, class TUuidValue, class TNameValue>
class WRWorkTcpCommServerTaskDealerActivator : public WRWorkTcpCommServerInterfaceActivator
{
public:
    //初始化工作TCP通讯服务器任务处理激活器。
    WRWorkTcpCommServerTaskDealerActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::enrollServerInterface(uuid(), this);
    }
    //释放当前对象所占用的相关资源。
    ~WRWorkTcpCommServerTaskDealerActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::cancelServerInterface(uuid());
    }

    //创建接口实例。
    WRWorkTcpCommServerInterface* create(int index, WRWorkTcpCommServerObject* target, void* reference)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommServerTaskDealer<T, TParamsParser, TResultWriter>(uuid(), name(), index, target, (WRTaskDealer*)reference);
    }
    //创建接口实例。
    WRWorkTcpCommServerInterface* create(int index, WRWorkTcpCommServerAffair* target, void* reference)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommServerTaskDealer<T, TParamsParser, TResultWriter>(uuid(), name(), index, target, (WRTaskDealer*)reference);
    }
};

#endif // WRWORKTCPCOMMSERVERTASKDEALER

